import os

# port = 68
# idx = 78

# os.system(f"docker run -itd -p 5722:22 --name monitor --network test-net --cap-add NET_ADMIN my/ubuntu /bin/bash")
import docker
import json
import os
from concurrent.futures import ThreadPoolExecutor
import pandas as pd

def create_multidocker(num):
    i = 0
    port = 10
    idx = 0
    while i < num:
        ret = os.system(f"docker run -itd -p {port+idx}22:22 --name node{i} --network test-net --cap-add NET_ADMIN my/ubuntu /bin/bash")
        if ret == 0:
            i += 1
        else:
            ret = os.system(f"docker rm node{i}")
        idx += 1

name_list = []
ip_list = []
mac_list = []
port_list = []

def list_containers_name():
    client = docker.from_env()

    containers = client.containers.list()
    for container in containers:
        container_info = container.attrs
        name = container_info['Name'].strip('/')
        name_list.append(name)
    return name_list
        
def list_containers_ip_mac():
    name_list.clear()
    ip_list.clear()
    mac_list.clear()
    port_list.clear()
    client = docker.from_env()

    containers = client.containers.list()

    for container in containers:
        container_info = container.attrs
        name = container_info['Name'].strip('/')
        
        # 默认网络配置
        default_network = list(container_info['NetworkSettings']['Networks'].values())[0]
        ip_address = default_network.get('IPAddress', 'N/A')
        mac_address = default_network.get('MacAddress', 'N/A')
        port = container_info["HostConfig"]["PortBindings"]["22/tcp"][0]["HostPort"]
        
        if name == "monitor":
            continue
        name_list.append(name)
        ip_list.append(ip_address)
        mac_list.append(mac_address)
        port_list.append(port)

        print(f"Container: {name}")
        print(f"  IP Address: {ip_address}")
        print(f"  MAC Address: {mac_address}")
        print(f"  Bind Port: {port}")
        print()
        
def execute_command_in_container(container_name, command):
    # 创建 Docker 客户端
    client = docker.from_env()

    try:
        # 获取容器
        container = client.containers.get(container_name)

        # 执行命令
        result = container.exec_run(command)

        # 获取命令的输出
        output = result.output.decode('utf-8')

        print(f"Output from container {container_name}:")
        print(output)
    except docker.errors.NotFound:
        print(f"Container '{container_name}' not found.")
    except docker.errors.APIError as e:
        print(f"Error executing command in container: {e}")

def execute_command_in_all_containers(command, stdout=True):
    client = docker.from_env()

    # 获取所有运行中的容器
    containers = client.containers.list()
    rets = []
    def execute(container):
        try:
            # 执行命令
            result = container.exec_run(command)

            # 获取命令的输出
            output = result.output.decode('utf-8')
            rets.append(output)
            if output.strip() != "" and stdout:
                print(f"Output from container {container.name}:")
                print(output)
        except docker.errors.APIError as e:
            print(f"Error executing command in container {container.name}: {e}")
    
    tmp = containers[0] 
    containers.remove(tmp)
    containers.append(tmp)
    
    for item in containers:
        execute(item)
    # with ThreadPoolExecutor(max_workers=10) as executor:
    #     futures = {executor.submit(execute, x) for x in containers}
    return rets

def execute_command(container, command, stdout=True):
    try:
        # 执行命令
        result = container.exec_run(command)

        # 获取命令的输出
        output = result.output.decode('utf-8')
        if output.strip() != "" and stdout:
            print(f"Output from container {container.name}:")
            print(output)
        return output
    except docker.errors.APIError as e:
        print(f"Error executing command in container {container.name}: {e}")
        return ""
def generate_config():
    vapi_srv = []
    for i in range(20):
        item = {
            "ip": f"172.18.1.{200+i}",
            "mac": "",
            "members": ip_list[i*3: i*3+3]
        }
        vapi_srv.append(item)
    return json.dumps(vapi_srv)

import subprocess

def read_file_from_docker(container_id, file_path):
    try:
        # Construct the docker exec command
        command = ["docker", "exec", container_id, "cat", file_path]
        
        # Execute the command and capture the output
        result = subprocess.run(command, capture_output=True, text=True, check=True)
        
        # Return the file content
        return result.stdout
    except subprocess.CalledProcessError as e:
        print(f"Error reading file from Docker container: {e}")
        return None
    
def copy_file_to_container(host_file_path, container_id, container_target_path):
    try:
        subprocess.run(["docker", "cp", host_file_path, f"{container_id}:{container_target_path}"], check=True)
        print(f"Successfully copied {host_file_path} to {container_id}:{container_target_path}")
    except subprocess.CalledProcessError as e:
        print(f"Error copying file: {e}")

def copy_file_from_container(container_id, container_target_path, host_file_path):
    try:
        subprocess.run(["docker", "cp", f"{container_id}:{container_target_path}", host_file_path], check=True)
        print(f"Successfully copied {container_id}:{container_target_path} to {host_file_path}")
    except subprocess.CalledProcessError as e:
        print(f"Error copying file: {e}")
        
def disconnet(container_id, network):
    try:
        subprocess.run(["docker", "network", "disconnect", network, container_id], check=True)
        print(f"Successfully disconnect  {container_id} from {network}")
    except subprocess.CalledProcessError as e:
        print(f"Error copying file: {e}")
        
def connect(container_id, network):
    try:
        subprocess.run(["docker", "network", "connect", network, container_id], check=True)
        print(f"Successfully connect  {container_id} from {network}")
    except subprocess.CalledProcessError as e:
        print(f"Error copying file: {e}")
        
def start_container(container_id):
    try:
        subprocess.run(["docker", "start", container_id], check=True)
        print(f"Successfully start  {container_id}")
    except subprocess.CalledProcessError as e:
        print(f"Error copying file: {e}")
        
def stop_container(container_id):
    try:
        subprocess.run(["docker", "stop", container_id], check=True)
        print(f"Successfully stop {container_id}")
    except subprocess.CalledProcessError as e:
        print(f"Error copying file: {e}")
        
def generate_node_list():
    title = ["name", "ip", "mac", "port"]
    data = []
    for name, ip, mac, port in zip(name_list, ip_list, mac_list, port_list):
        data.append({"name": name, "ip": ip, "mac": mac, "port": port})
    df = pd.DataFrame(columns=title, data=data)
    df.to_csv("node1.csv", index=False)

if __name__ == '__main__':
    # create_multidocker(60)
    # list_containers_ip_mac()
    list_containers_name()
    # for name in name_list:
    #     connet(name, "test-net")
    # generate_node_list()
    # print(ip_list)
    # execute_command_in_all_containers("service ssh start", True)
    # print(generate_config())
    # for node in name_list:
    #     copy_file_to_container("C:/Users/YML/Desktop/tmp/bin.tar.gz", node, "/opt/bin.tar.gz")
    # execute_command_in_all_containers("sh -c 'cd /opt && rm -rf bin && tar -zxvf bin.tar.gz'", False)

    for node in name_list:
        copy_file_to_container("./router.json", node, "/opt/bin/res/router.json")
        # copy_file_to_container("./devsrv.json", node, "/opt/bin/res/devsrv.json")
    #     copy_file_to_container("C:/Users/YML/Desktop/tmp/brelect", node, "/opt/bin/brelect")
    #     copy_file_to_container("C:/Users/YML/Desktop/tmp/meidator", node, "/opt/bin/meidator")
        # copy_file_to_container("C:/Users/YML/Desktop/tmp/whitelist", node, "/opt/bin/whitelist")
    #     copy_file_to_container("C:/Users/YML/Desktop/tmp/blueriver_control", node, "/opt/bin/blueriver_control")
        # copy_file_to_container("C:/Users/YML/Desktop/tmp/rediselect", node, "/opt/bin/rediselect")
    #     copy_file_to_container("./reset_net.sh", node, "/root/reset_net.sh")

    # execute_command_in_all_containers("sh -c 'chmod +x /opt/bin/rediselect'")
        # copy_file_to_container("C:/Users/YML/Desktop/tmp/bin.tar.gz", node, "/opt/bin.tar.gz")
        # push_file_via_scp("C:/Users/YML/Desktop/tmp/bin.tar.gz", "/opt/bin.tar.gz", "127.0.0.1",  int(port), "root", "123456")
        # push_file_via_scp("C:/Users/YML/Desktop/tmp/blueriver_control", "/opt/bin/blueriver_control", "127.0.0.1",  int(port), "root", "123456")
        # push_file_via_scp("./killserver.sh", "/opt/bin/killserver.sh", "127.0.0.1",  int(port), "root", "123456")
    # execute_command_in_all_containers("sh -c 'cd /opt && rm -rf bin && tar -zxvf bin.tar.gz'", False)
    # execute_command_in_all_containers("sh -c ifconfig")
    
    # 检查所有配置文件都一致
    # with open("devsrv.json", "r") as f:
    # with open("router.json", "r") as f:
    #     sVal = json.load(f)
    #     sVal = json.dumps(sVal)
    #     print(sVal)
    
    
    # for name in name_list:
    #     # file_path = "/opt/bin/res/devsrv.json"  # Replace with the file path inside the container
    #     file_path = "/opt/bin/res/router.json"  # Replace with the file path inside the container

    #     file_content = read_file_from_docker(name, file_path)
    #     jVal = json.loads(file_content)
    #     docker_config = json.dumps(jVal)
    #     # print(docker_config)
    #     assert(sVal == docker_config)
